/**
 * Check Sum class
 */
package com.flute.framework.data.impl;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import com.flute.framework.FluteMonitor;
import com.flute.framework.StandardDate;
import com.flute.framework.data.Sum;
import com.flute.framework.data.constants.Constants;
import com.flute.framework.data.mysql.MySQLConnectionUtil;
import com.flute.framework.monitor.EventLogger;
import com.flute.framework.util.EventLoggerUtil;
import com.flute.tools.data.DataIterator;
import com.flute.tools.data.DataRecord;
import com.flute.tools.data.mysql.NewMysqlHandler;
import com.flute.tools.util.ExceptionUtil;
import com.flute.tools.util.exceptoin.DataParserException;

/**
 * @author Jazz
 * 
 */
public class CheckSumHandler {
	private String name;
	private RawSumCheckParser parser;
	private String checkSumPath;
	private String failedPath;
	private String backupPath;
	private Double updateThreshold;

	public Double getUpdateThreshold() {
		return updateThreshold;
	}

	public void setUpdateThreshold(Double updateThreshold) {
		this.updateThreshold = updateThreshold;
	}

	public RawSumCheckParser getParser() {
		return parser;
	}

	public void setParser(RawSumCheckParser parser) {
		this.parser = parser;
	}

	public String getCheckSumPath() {
		return checkSumPath;
	}

	public void setCheckSumPath(String checkSumPath) {
		this.checkSumPath = checkSumPath;
	}

	public String getFailedPath() {
		return failedPath;
	}

	public void setFailedPath(String failedPath) {
		this.failedPath = failedPath;
	}

	public String getBackupPath() {
		return backupPath;
	}

	public void setBackupPath(String backupPath) {
		this.backupPath = backupPath;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void checkSum() {
		if (parser == null || StringUtils.isEmpty(checkSumPath)
				|| StringUtils.isEmpty(failedPath)
				|| StringUtils.isEmpty(backupPath)) {
			throw new NullPointerException(
					"parser,checkSumPath,failedPath,backupPath不能为空");
		}
		File file = new File(checkSumPath);
		File[] files = null;
		if (file.exists()) {
			files = file.listFiles();
			if (files == null) {
				EventLoggerUtil.info("没有校验和文件推送存在，返回True", FluteMonitor
						.getImporterKey());
				return;
			}
		} else {
			EventLoggerUtil.info("文件夹不存在，返回True", FluteMonitor.getImporterKey());
			return;
		}
		for (File checkSumFile : files) {
			try {
				List<Sum> sums = parser.parse(checkSumFile);
				NewMysqlHandler handler = MySQLConnectionUtil
						.getNewMysqlHandler();

				for (Sum sum : sums) {
					check(handler, sum, MySQLConnectionUtil.getSongTableName());

					check(handler, sum, MySQLConnectionUtil
							.getSingerTableName());

					check(handler, sum, MySQLConnectionUtil.getAlbumTableName());
				}

				backup(checkSumFile);
			} catch (DataParserException e) {
				File destDir = new File(MySQLConnectionUtil
						.getCheckSumFailedPath());
				try {
					FileUtils.moveFileToDirectory(checkSumFile, destDir,
							Boolean.TRUE);
				} catch (IOException e1) {
					throw new RuntimeException("移动" + checkSumFile.getName()
							+ "到" + destDir.getPath() + "失败");
				}
				throw new RuntimeException("解析校验和文件失败");
			}
		}
	}

	private void backup(File file) {
		File destDir = new File(backupPath
				+ File.separator
				+ new StandardDate(System.currentTimeMillis())
						.toSpecialDateString());
		try {
			EventLoggerUtil.info("开始备份" + file.getName(), FluteMonitor
					.getImporterKey());
			FileUtils.moveFileToDirectory(file, destDir, Boolean.TRUE);
			EventLoggerUtil.info("备份" + file.getName() + "成功", FluteMonitor
					.getImporterKey());
		} catch (IOException e) {
			EventLoggerUtil.info("备份文件失败"
					+ ExceptionUtil.getExceptionContent(e), FluteMonitor
					.getImporterKey());
			throw new RuntimeException("备份" + file.getName() + "到"
					+ destDir.getPath() + "失败");
		}
	}

	private void check(final NewMysqlHandler handler, final Sum sum,
			final String name) {
		if (StringUtils.isNotEmpty(sum.getName()) && sum.getName().equals(name)) {
			DataIterator<DataRecord> it = handler
					.iterator("SELECT count(*) as checksum FROM "
							+ MySQLConnectionUtil.getAllRecordsTable(name));
			if (it.hasNext()) {
				DataRecord dr = it.next();
				String checkSum = dr.getFieldValue(Constants.CHECK_SUM);
				if (Math.abs(Double.valueOf(checkSum)
						- Double.valueOf(sum.getValue())) > updateThreshold) {
					EventLoggerUtil.error("校验" + name + "失败。传输过来的和是" + checkSum
							+ ",代校验的和是" + sum.getValue(), FluteMonitor
							.getImporterKey());
				} else {
					EventLoggerUtil.info("校验" + name + "成功。传输过来的和是" + checkSum
							+ ",代校验的和是" + sum.getValue(), FluteMonitor
							.getImporterKey());
				}
			}
		}
	}

	/**
	 * @param args
	 * @throws DataParserException
	 */
	public static void main(String[] args) throws DataParserException {
		EventLogger.startNewEvent(FluteMonitor.getImporterKey());
		CheckSumHandler handler = new CheckSumHandler();
		handler.setBackupPath("E:\\home\\release\\lily\\checksum\\backup");
		handler
				.setCheckSumPath("E:\\home\\release\\lily\\rawData\\sumcheck\\sumcheck.xml");
		handler.setFailedPath("E:\\home\\release\\lily\\checksum\\failed");
		handler.setParser(new RawSumCheckParser());
		handler.checkSum();
	}
}
